const express = require("express");
// 导入jsonwebtoken中间件--- 生成jwt字符串
const jwt = require("jsonwebtoken");
// 导入express-jwt中间件 --- 解析jwt字符串
const { expressjwt: expressJwt } = require("express-jwt");

const app = express();

// 配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }));
app.use(express.json());

// 定义一个密钥
const secret = "zwx!@#2024";

// 将jwt字符串还原为JSON对象
// 客户端每次请求都主动通过请求头Authorization携带token数据
app.use(
  expressJwt({
    // 指定密钥
    secret: secret,
    // 指定验证的算法
    algorithms: ["HS256"],
  }).unless({
    // 配置不需要进行token验证的接口
    path: [/^\/api\//],
  })
);

// 登录接口
app.post("/api/login", (req, res) => {
  if (req.body.username !== "admin" || req.body.password !== "000000") {
    res.send({
      status: 401,
      message: "用户名或密码错误",
    });
    return;
  }
  res.send({
    status: 200,
    message: "登录成功",
    // 调用jwt.sign()方法生产jwt字符串, 并通过token属性发送给客户端
    token: jwt.sign({ username: req.body.username }, secret, {
      expiresIn: "1h",
      algorithm: "HS256",
    }),
  });
});

// 个人信息接口
app.get("/myinfo", (req, res) => {
  // 如果程序能够运行到这里, 说明token验证通过了
  console.log(req.auth); // req.auth
  console.log("验证通过!");
  //console.log(req);
  res.send({
    status: 200,
    message: "获取用户信息成功",
    data: req.auth, // 将用户信息发送给客户端
  });
});

// 全局错误处理中间件
app.use((err, req, res, next) => {
  // token验证失败导致的错误
  if (err.name === "UnauthorizedError") {
    return res.send({
      status: 401,
      message: "无效的token",
    });
  }
  // 未知错误
  res.send({
    status: 500,
    message: "未知的错误",
  });
});

app.listen(3000, () => {
  console.log("express server running at http://127.0.0.1:8080");
});
